package com.github.wxiaoqi.security.crm.core.biz;

import java.math.BigDecimal;
import java.text.Bidi;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.wxiaoqi.security.auth.common.util.SnowFlake;
import com.github.wxiaoqi.security.common.crm.request.OutAccountRequest;
import com.github.wxiaoqi.security.common.crm.request.UnFreAndOutAccountRequest;
import com.github.wxiaoqi.security.common.enums.AccountStateEnums;
import com.github.wxiaoqi.security.common.enums.CustomerTypeEnums;
import com.github.wxiaoqi.security.common.enums.InOutFlagEnums;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.EntityUtils;
import com.github.wxiaoqi.security.common.util.MD5;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccount;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccount;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.UnfreezeJournal;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.UnfreezeJournalMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * 个人或者商户解冻并出账接口
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class CommonOutAccountBiz {
	@Value("${bountyHunter.balanceSaltValue}")
	private String balanceSaltValue;
	@Autowired
	private MerchantAccountJournalMapper merchantAccountJournalMapper;
	@Autowired
	private MerchantAccountMapper merchantAccountMapper;
	@Autowired
	private UnfreezeJournalMapper unfreezeJournalMapper;
	@Autowired
	private PersonalAccountMapper personalAccountMapper;
	@Autowired
	private PersonalAccountJournalMapper personalAccountJournalMapper;
	/**
	 * 个人或者商户解冻并出账接口
	 * 若是商户：
	 * 1.商户账户冻结金额扣除
	 * 2.新增商户流水记录、解冻流水记录
	 * 若是个人：
	 * 1.个人账户冻结金额扣除
	 * 2.新增个人账户流水记录、解冻流水记录
	 */
	public Map<String, Object> unFreAndOutAccount(UnFreAndOutAccountRequest unFreAndOutAccountRequest) {
		log.info("个人或者商户解冻并出账接口-请求参数：{}" + EntityUtils.beanToMap(unFreAndOutAccountRequest));
		Map<String, Object> response = new HashMap<String, Object>();
		/**
		 * 根据冻结流水号查询是否被解冻
		 * */
		try {
			UnfreezeJournal queryUnfreezeJournal = new UnfreezeJournal();
			queryUnfreezeJournal.setFreezeId(unFreAndOutAccountRequest.getFreezeId());
			UnfreezeJournal unfreezeJournal=unfreezeJournalMapper.selectOne(queryUnfreezeJournal);
			if(null!=unfreezeJournal){
				log.info("个人或者商户解冻并出账接口--冻结资金已解冻");
				response.put("code", ResponseCode.UNFREEZE_IS_EXIST.getCode());
				response.put("msg", ResponseCode.UNFREEZE_IS_EXIST.getMessage());
				return response;
			}
			
			if(unFreAndOutAccountRequest.getCustomerType().equals(CustomerTypeEnums.mer_user.getCode())){
				MerchantAccount queryMerchantAccount=new MerchantAccount();
				queryMerchantAccount.setPlatformId(unFreAndOutAccountRequest.getPlatformId());
				queryMerchantAccount.setMerchantId(unFreAndOutAccountRequest.getMerchantId());
				queryMerchantAccount.setMerchantType((unFreAndOutAccountRequest.getMerchantType()));
				queryMerchantAccount.setAccountType(unFreAndOutAccountRequest.getAccountType());
				MerchantAccount merchantAccount= merchantAccountMapper.selectOne(queryMerchantAccount);
				if(null!=merchantAccount&&merchantAccount.getStatus().equals(AccountStateEnums.normal.getCode())){
					if (!MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())) {
						response.put("code", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getCode());
						response.put("msg", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getMessage());
						log.info("个人或者商户解冻并出账接口-返回参数。。。。。。{}", response);
						return response;
					}
					if(merchantAccount.getAccountBalance().compareTo(new BigDecimal(unFreAndOutAccountRequest.getUnFreAmt()))<0){//商户账户余额不足
						response.put("code", ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH.getCode());
						response.put("msg", ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH.getMessage());
						log.info("个人或者商户解冻并出账接口-返回参数。。。。。。{}", response);
						return response;
					}
					
					merchantAccount.setFreezeBalance(queryMerchantAccount.getFreezeBalance().subtract(new BigDecimal(unFreAndOutAccountRequest.getUnFreAmt())));
					merchantAccount.setCheckSum(MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
					merchantAccountMapper.updateByPrimaryKeySelective(merchantAccount);
				}else{
					log.info("个人或者商户解冻并出账接口--商户账户不存在或者被账户被冻结");
					response.put("code", ResponseCode.MER_ACC_NOTEXIST.getCode());
					response.put("msg", ResponseCode.MER_ACC_NOTEXIST.getMessage());
					return response;
				}
				MerchantAccountJournal merAccountJournal=new MerchantAccountJournal();
				merAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
				merAccountJournal.setPlatformId(unFreAndOutAccountRequest.getPlatformId());
				merAccountJournal.setMerchantId(unFreAndOutAccountRequest.getMerchantId());
				merAccountJournal.setAccountId(merchantAccount.getAccountId());
				merAccountJournal.setOrderNo(unFreAndOutAccountRequest.getOrderNo());
				merAccountJournal.setInOutFlag(InOutFlagEnums.out.getCode());//出账 
				merAccountJournal.setTradeAmt(new BigDecimal(unFreAndOutAccountRequest.getUnFreAmt()));
				merAccountJournal.setTradeType(unFreAndOutAccountRequest.getTradeType());
				merAccountJournal.setCreateTime(new Date());
				merchantAccountJournalMapper.insertSelective(merAccountJournal);
			}
			/**
			 * 客户类型-若是个人 : 则需要个人账户余额增加、新增个人账户流水记录
			 * */
			if(unFreAndOutAccountRequest.getCustomerType().equals(CustomerTypeEnums.per_user.getCode())){
				PersonalAccount queryPersonalAccount = new PersonalAccount();
				queryPersonalAccount.setPlatformId(unFreAndOutAccountRequest.getPlatformId());
				queryPersonalAccount.setPersonalId(unFreAndOutAccountRequest.getPersonalId());
				queryPersonalAccount.setAccountType(unFreAndOutAccountRequest.getAccountType());
				PersonalAccount personalAccount = personalAccountMapper.selectOne(queryPersonalAccount);
				if(null!=personalAccount&&personalAccount.getStatus().equals(AccountStateEnums.normal.getCode())){
					if(!MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
						log.info("个人或者商户解冻并出账接口--个人账户余额不匹配");
						response.put("code", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getCode());
						response.put("msg", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getMessage());
						log.info("个人或者商户解冻并出账接口。。。。。。{}", response);
						return response;
					}
					personalAccount.setAccountBalance(personalAccount.getAccountBalance().add(new BigDecimal(unFreAndOutAccountRequest.getUnFreAmt())));
					personalAccount.setCheckSum(MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
					personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
				}else{
					log.info("个人或者商户解冻并出账接口--个人账户不存在或者被冻结");
					response.put("code", ResponseCode.PER_ACC_NOTEXIST.getCode());
					response.put("msg", ResponseCode.PER_ACC_NOTEXIST.getMessage());
					return response;
				}
				PersonalAccountJournal personalAccountJournal=new PersonalAccountJournal();
				personalAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
				personalAccountJournal.setPlatformId(unFreAndOutAccountRequest.getPlatformId());
				personalAccountJournal.setPersonalId(unFreAndOutAccountRequest.getPersonalId());
				personalAccountJournal.setAccountId(personalAccount.getAccountId());
				personalAccountJournal.setAccountType(personalAccount.getAccountType());
				personalAccountJournal.setOrderNo(unFreAndOutAccountRequest.getOrderNo());
				personalAccountJournal.setInOutFlag(InOutFlagEnums.out.getCode());//来往标志  1：入账   2：出账
				personalAccountJournal.setTradeAmt(new BigDecimal(unFreAndOutAccountRequest.getUnFreAmt()));
				personalAccountJournal.setTradeType(unFreAndOutAccountRequest.getTradeType());//交易类型（支付:01，退款:02，提现:03，充值:04）
				personalAccountJournal.setCreateTime(new Date());
				personalAccountJournalMapper.insertSelective(personalAccountJournal);
			}
			/***
			 * 新增解冻流水记录
			 * */
			queryUnfreezeJournal.setJournalId(String.valueOf(SnowFlake.getId()));
			queryUnfreezeJournal.setTradeType(unFreAndOutAccountRequest.getTradeType());//交易类型（支付:01，退款:02，提现:03，充值:04）
			queryUnfreezeJournal.setUnfreezeBalance(new BigDecimal(unFreAndOutAccountRequest.getUnFreAmt()));
			queryUnfreezeJournal.setCreateTime(new Date());
			unfreezeJournalMapper.insertSelective(queryUnfreezeJournal);
			response.put("code", ResponseCode.OK.getCode());
			response.put("msg", ResponseCode.OK.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			log.info("个人或者商户解冻并出账接口-报错--"+e.getMessage());
			response.put("code", ResponseCode.ABNORMAL_FIELDS.getCode());
			response.put("msg", ResponseCode.ABNORMAL_FIELDS.getMessage());
			return response;
		}
		return response;
	}
	/**
	 * 个人或者商户直接出账接口
	 * 若是商户:
	 * 1.商户账户余额扣除，2.新增商户账户流水
	 * 若是个人:
	 * 1.个人账户余额扣除  2.新增个人账户流水
	 */
	public Map<String, Object> outAccount(OutAccountRequest outAccountRequest) {
		log.info("个人或者商户直接出账接口-请求参数：{}" + EntityUtils.beanToMap(outAccountRequest));
		Map<String, Object> response = new HashMap<String, Object>();
		try {
			if(outAccountRequest.getCustomerType().equals(CustomerTypeEnums.mer_user.getCode())){
				/**
				 * 修改商户账户余额
				 * */
				MerchantAccount queryMerchantAccount=new MerchantAccount();
				queryMerchantAccount.setPlatformId(outAccountRequest.getPlatformId());
				queryMerchantAccount.setMerchantId(outAccountRequest.getMerchantId());
				queryMerchantAccount.setMerchantType(outAccountRequest.getMerchantType());
				queryMerchantAccount.setAccountType(outAccountRequest.getAccountType());
				MerchantAccount merchantAccount= merchantAccountMapper.selectOne(queryMerchantAccount);
				if(null!=merchantAccount&&merchantAccount.getStatus().equals(AccountStateEnums.normal.getCode())){
					//校验商户账户余额是否匹配  和商户账户余额是否充足
					if(!MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(merchantAccount.getCheckSum())){
						response.put("code", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getCode());
						response.put("msg", ResponseCode.MER_ACC_BALANCE_NOT_MATE.getMessage());
						log.info("个人或者商户直接出账接口 返回参数。。。。。。{}", response);//
						return response;
					}
					if(!MD5.sign(merchantAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(new BigDecimal(outAccountRequest.getOutAccAmt()))){
						response.put("code", ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH.getCode());
						response.put("msg", ResponseCode.MER_ACC_BALANCE_NOT_ENOUGH.getMessage());
						log.info("个人或者商户直接出账接口 返回参数。。。。。。{}", response);
						return response;
					}
					merchantAccount.setAccountBalance(queryMerchantAccount.getAccountBalance().subtract(new BigDecimal(outAccountRequest.getOutAccAmt())));
					merchantAccountMapper.updateByPrimaryKeySelective(merchantAccount);
				}else{
					log.info("个人或者商户直接出账接口--商户账户不存在或者被冻结");
					response.put("code", ResponseCode.MER_ACC_NOTEXIST.getCode());
					response.put("msg", ResponseCode.MER_ACC_NOTEXIST.getMessage());
					return response;
				}
				/***
				 * 新增商户账户流水记录
				 * */
				MerchantAccountJournal merAccountJournal=new MerchantAccountJournal();
				merAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
				merAccountJournal.setPlatformId(outAccountRequest.getPlatformId());
				merAccountJournal.setMerchantId(outAccountRequest.getMerchantId());
				merAccountJournal.setAccountId(merchantAccount.getAccountId());
				merAccountJournal.setOrderNo(outAccountRequest.getOrderNo());
				merAccountJournal.setInOutFlag(InOutFlagEnums.out.getCode());//出账 
				merAccountJournal.setTradeAmt(new BigDecimal(outAccountRequest.getOutAccAmt()));
				merAccountJournal.setTradeType(outAccountRequest.getTradeType());//交易类型（支付:01，退款:02，提现:03，充值:04）
				merAccountJournal.setCreateTime(new Date());
				merchantAccountJournalMapper.insertSelective(merAccountJournal);
				merchantAccountJournalMapper.insertSelective(merAccountJournal);
			}
			
			if(outAccountRequest.getCustomerType().equals(CustomerTypeEnums.per_user.getCode())){
				PersonalAccount queryPersonalAccount = new PersonalAccount();
				queryPersonalAccount.setPlatformId(outAccountRequest.getPlatformId());
				queryPersonalAccount.setPersonalId(outAccountRequest.getPersonalId());
				queryPersonalAccount.setAccountType(outAccountRequest.getAccountType());
				PersonalAccount personalAccount = personalAccountMapper.selectOne(queryPersonalAccount);
				if(null!=personalAccount&&personalAccount.getStatus().equals(AccountStateEnums.normal.getCode())){
					if(!MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8").equals(personalAccount.getCheckSum())){
						response.put("code", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getCode());
						response.put("msg", ResponseCode.PER_ACC_BALANCE_NOT_MATE.getMessage());
						log.info("个人或者商户直接出账接口 返回参数。。。。。。{}", response);
						return response;
					}
					personalAccount.setAccountBalance(personalAccount.getAccountBalance().subtract(new BigDecimal(outAccountRequest.getOutAccAmt())));
					personalAccount.setCheckSum(MD5.sign(personalAccount.getAccountBalance().toString(), balanceSaltValue, "utf-8"));
					personalAccountMapper.updateByPrimaryKeySelective(personalAccount);
				}else{
					log.info("个人或者商户直接出账接口--个人账户不存在或者被冻结");
					response.put("code", ResponseCode.PER_ACC_NOTEXIST.getCode());
					response.put("msg", ResponseCode.PER_ACC_NOTEXIST.getMessage());
					return response;
				}
				/***
				 * 新增个人账户流水记录
				 * */
				PersonalAccountJournal personalAccountJournal=new PersonalAccountJournal();
				personalAccountJournal.setJournalId(String.valueOf(SnowFlake.getId()));
				personalAccountJournal.setPlatformId(outAccountRequest.getPlatformId());
				personalAccountJournal.setPersonalId(outAccountRequest.getPersonalId());
				personalAccountJournal.setAccountId(personalAccount.getAccountId());
				personalAccountJournal.setAccountType(personalAccount.getAccountType());
				personalAccountJournal.setOrderNo(outAccountRequest.getOrderNo());
				personalAccountJournal.setInOutFlag(InOutFlagEnums.out.getCode());//来往标志  1：入账   2：出账
				personalAccountJournal.setTradeAmt(new BigDecimal(outAccountRequest.getOutAccAmt()));
				personalAccountJournal.setTradeType(outAccountRequest.getTradeType());//交易类型（支付:01，退款:02，提现:03，充值:04）
				personalAccountJournal.setCreateTime(new Date());
				personalAccountJournalMapper.insertSelective(personalAccountJournal);
			}
			response.put("code", ResponseCode.OK.getCode());
			response.put("msg", ResponseCode.OK.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			log.info("个人或者商户直接出账接口 报错--"+e.getMessage());
			response.put("code", ResponseCode.ABNORMAL_FIELDS.getCode());
			response.put("msg", ResponseCode.ABNORMAL_FIELDS.getMessage());
			return response;
		}
		return response;
	}
}
